var mongoose=require('mongoose');
var markdown=require('markdown').markdown;
var mock = require('./mock');
var ObjectID=require('mongodb').ObjectID;
var tags=require('../config/config').tags;

var PostSchema = new mongoose.Schema({
    title:{
        type:String,
        required:true
    },
    desc:{
        type:String,
        required:true,
        set: function (desc) {
            return desc.replace(/\r\n/g,'<br/>').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        }
    },
    content:{
        type:String,
        required:true
    },
    user:{
        type:Object,
        required:true
    },
    date:{
        type:Date
    },
    comments:{
        type:Array
    },
    tags:{
        type:Array,
        enum:tags
    },
    pv:{
        type:Number,
        default:0
    },
    reprint:{
        type:Object,
        default:{
            from:null,
            to:[]
        }
    }
});

PostSchema.virtual('contentHTML').get(function (){
    return markdown.toHTML(this.content);
});

PostSchema.virtual('time').get(function (){
    var d=this.date;
    return [d.getFullYear(), d.getMonth()+1, d.getDate()].join('-')+' '+[d.getHours(), d.getMinutes(), d.getSeconds()].join(':');
});

//分布获取Post
PostSchema.statics.getPage= function (query,page,limit,cb) {
    var coll=this;
    coll.count(query, function (err, total) {
        if(err){
            return cb(err);
        }
        coll.find(query,{__v:0},{skip:(page-1)*limit,limit:limit,sort:{date:-1,title:1}},function (err, docs) {
            if(err)return cb(err);
            //console.log('Post.getPage>posts:',docs);
            cb(null,docs,total);
        });
    });
};

PostSchema.statics.getById= function (post_id,cb) {
    var coll=this;
    this.findOne({_id:post_id}, function (err,post) {
        if(err){
            return cb(err);
        }
        //更新阅读数
        coll.update({_id:post_id},{$inc:{pv:1}}, function (err) {
            if(err)return cb(err);
            cb(null,post);
        });
    });
};

PostSchema.statics.addComment= function (post_id,comment,cb) {
    this.findOneAndUpdate({_id:new ObjectID(post_id)},{$push:{comments:{user:comment.user,content:comment.content,time:comment.time}}},{new:true},function (err,post) {
        if(err)return cb(err);
        cb(null,post);
    });
};

//编辑更新Post
PostSchema.statics.patch= function (data,cb) {
    //console.log('update Post > data:',data);
    var clean={},self=this;
    if(data.body.tags){
        if('object'== typeof data.body.tags){
            clean.tags=data.body.tags;
        }else{
            clean.tags=[data.body.tags];
        }
        clean.tags=clean.tags.filter(function (tag) {
            return !!~tags.indexOf(tag);
        });
        if(!clean.tags.length){//输入值都不合法，则不修改
            clean.tags=[];
        }
    }else{
        clean.tags=[];
    }
    if(data.body.desc){
        clean.desc=data.body.desc;
    }
    if(data.body.content){
        clean.content=data.body.content;
    }
    //console.log('update Post > clean:',clean);
    this.findOneAndUpdate({_id:new ObjectID(data._id),'user._id':data.user._id},{$set:clean},{new:true},function (err,post) {
        //console.log('update ret:',ret);
        if(err)return cb(err);
        cb(null,post);
    });
};

//删除
PostSchema.statics.removePost= function (data,cb) {
    //console.log('delete data:',data);
    var self=this;
    this.findOneAndRemove({_id:new ObjectID(data.post_id),'user.name':data.name}, function (err,post) {
        if(err)return cb(err);
        if(!post)return cb({message:'博客不存在-ErrA'});
        var fromId;
        if(post.reprint.from){//转载来的文章
            fromId=post.reprint.from.origin_post_id;
            //更新原Blog的reprint.to数据
            self.update({_id:new Object(fromId)},{$pull:{'reprint.to':{reprint_post_id:post._id}}}, function (err,ret) {
                if(err)return cb({message:'更新转载的原始博客错误-ErrC'});
                cb(null);
            });
        }else{
            cb(null);
        }
    });
};

//转载
PostSchema.statics.reprint= function (post,user,cb) {
    //判断是否以转载过
    var yet=post.reprint.to.find(function (item) {
        return user.name === item.username;
    });
    if(yet)return cb({yet:yet});
    var coll=this;
    //添加数据并保存
    post.title='[转载]'+post.title;
    post.reprint.from={
        origin_post_id:post.origin_id.toString(),
        user_id:post.origin_user._id.toString(),
        username:post.origin_user.name
    };
    post.save(function (err, reprint) {
        if(err)return cb(err);
        //console.log('reprint save ret:',reprint);
        //更新原Post的reprint.to数组
        coll.update({_id:post.reprint.from.origin_post_id},{
            $push:{'reprint.to':{username:user.name,user_id:user._id,reprint_post_id:reprint._id}}
        }, function (err,ret) {
            //console.log('reprint update ret:',err,ret);
            if(err)return cb(err);
            //console.log('update!!');
            cb(null,reprint);
        });
    });
};

//Tags
PostSchema.statics.getTags= function (cb) {
  this.distinct('tags', function (err, tags) {
      cb(err,tags);
  });
};

//搜索
PostSchema.statics.search=function(keyword,page,limit,cb){
    if(!keyword || /\W/.test(keyword))return cb({message:'搜索关键词非法-ErrA'});
    PostSchema.statics.getPage.call(this,{title:RegExp(keyword,'i')},page,limit,cb);
};

//归档分类
PostSchema.statics.getArchive= function (cb) {
    this.find({},{},{sort:{date:-1}},function (err,posts) {
        //console.log('getArchive find:',err,posts);
        if(err)return cb(err);
        if(!posts.length)return cb(null,null);//无数据
        var list={};
        posts.forEach(function (doc) {
            var d=doc.date,month=d.getMonth()+ 1,date;
            month=month<10?'0'+month:month;
            date=[d.getFullYear(),month].join('-');
            if(!list[date])list[date]=[];
            list[date].push({
                _id:doc._id,
                title:doc.title,
                date:mock.dateFormat(d,'all',true),
                user:doc.user
            });
        });
        //console.log('getArchive:',list);
        cb(null,list);
    });
};


var Post = mongoose.model('Post',PostSchema);
module.exports= Post;
